package com.ruoyi.system.service.standard.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.controller.standard.SSEController;
import com.ruoyi.system.domain.standard_relevant.StandardExcel;
import com.ruoyi.system.domain.standard_relevant.StandardSystemData;
import com.ruoyi.system.service.standard.IStandardExcelService;
import com.ruoyi.system.service.standard.IStandardSystemDataService;
import com.ruoyi.system.util.ISDataScoreUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Service
public class DataProcessingService {

    @Autowired
    private IStandardSystemDataService standardSystemDataService;
    @Autowired
    private SSEController sseController;
    @Autowired
    private IStandardExcelService standardExcelService;

    @Async
    public CompletableFuture<Void> processCalculation(String standardCode,Integer type,StandardExcel old_standardExcel) {
        return CompletableFuture.runAsync(() -> {
            try {
                // 假设数据分析和数据库操作
                Map<Integer, Float> calRes = calScore(standardCode, type);
                if(calRes == null){
                    sseController.sendMessage("未获得计算结果，请检查");
                    System.out.println("calRes 为 null");
                    return;
                }
                if (calRes.isEmpty()) {
                    sseController.sendMessage("未获得计算结果，请检查");
                    System.out.println("calRes 为空");
                    return;
                }

                StandardExcel newStandardExcel = createResItem(standardCode, calRes, type);

                if (newStandardExcel == null) {
                    sseController.sendMessage("未获得计算结果，请检查");
                    return;
                }

                if (old_standardExcel == null) {
                    int res = standardExcelService.insertStandardExcel(newStandardExcel);
                    if (res > 0) {
                        sseController.sendMessage("新增原始数据得分成功");
                    } else {
                        sseController.sendMessage( "新增原始数据得分失败");
                    }
                } else if (old_standardExcel.getType() == type) {
                    int res = standardExcelService.updateStandardExcel(newStandardExcel);
                    if (res > 0) {
                        sseController.sendMessage( "更新原始数据得分成功");
                    } else {
                        sseController.sendMessage("更新原始数据得分失败");
                    }
                } else {
                    sseController.sendMessage("出现异常错误，请检查");
                }
            } catch (Exception e) {
                sseController.sendMessage("发生错误: " + e.getMessage());
            }
        });
    }

    /** 计算，并根据结果创建一个 standardExcel 对象 */
    public StandardExcel createResItem(String standardCode,Map<Integer,Float> calRes,Integer type) throws NoSuchFieldException {
        if (calRes == null || calRes.isEmpty()){
            return null; //"未获得计算结果，请检查"
        }
        // 新建一项
        StandardExcel standardExcel = new StandardExcel();
        standardExcel.setStandardCode(standardCode);
        standardExcel.setType(type);

        // id:name
        ISDataScoreUtil isDataScoreUtil = new ISDataScoreUtil();
        Map<Integer,String> indicatorMap = isDataScoreUtil.getIndicatorMap();

        for (Map.Entry<Integer, Float> entry : calRes.entrySet()) {
            Integer id = entry.getKey();
            Float score = entry.getValue();
            // 保存
            String indicatorName = indicatorMap.get(id);
            // 如果存在对应的属性:
            if (indicatorName != null) {
                // 反射设置值
                try {
                    Field field = StandardExcel.class.getDeclaredField(indicatorName);
                    // 如果字段存在，设置可访问
                    field.setAccessible(true);
                    // 反射设置值
                    field.set(standardExcel, score);
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

        }
        // 返回 standardExcel对象
        return standardExcel;
    }

    /**
     *  获取传递的参数
     *  中国主导：params : {"target":"A1","x":4,"y":6,"file1_path":"path1","file2_path":"path2"}
     *  中国参与：params : {"target":"A11","x":4,"vote_record_path":"path1","meeting_record_path":"path2"}
     */

    /** 遍历 usageDataMap 的 key 即可获取所有 usage*/
    public JSONObject getParams(Map<String,String>usageDataMap,Map<String,String> paramsTypeMap,String indicatorName){
        JSONObject paramsObject = new JSONObject();
        // 遍历 usageDataMap 中的键
        for (Map.Entry<String, String> entry : usageDataMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();

            // 检查是否存在 key 对应的参数类型映射
            if (paramsTypeMap.containsKey(key)) {
                String paramType = paramsTypeMap.get(key);

                // 如果值为 null，表示缺少必要项，返回 null
                if (value == null) {
                    return null;
                }
                // 根据 paramType 类型设置值
                paramsObject.put(paramType, value);
            }
        }
        // 检查是否包含所有必要的字段
        if (paramsObject.isEmpty()) {
            return null;  // 没有找到任何有效的参数，返回 null
        }
        // 处理  最初提案和最终文本 (url 转 path)
        if (paramsObject.containsKey("file1_path") ) {
            String file1Path = paramsObject.getString("file1_path");
            paramsObject.put("file1_path", getTrueFilePath(file1Path));
        }
        if(paramsObject.containsKey("file2_path")){
            String file2Path = paramsObject.getString("file2_path");
            paramsObject.put("file2_path", getTrueFilePath(file2Path));
        }

        // 处理  投票记录和会议记录 (url 转 path)
        if (paramsObject.containsKey("vote_record_path") ) {
            String file1Path = paramsObject.getString("vote_record_path");
            paramsObject.put("vote_record_path", getTrueFilePath(file1Path));
        }
        if(paramsObject.containsKey("vote_record_path")){
            String file2Path = paramsObject.getString("vote_record_path");
            paramsObject.put("vote_record_path", getTrueFilePath(file2Path));
        }
        // 添加 target(哪个指标)
        paramsObject.put("target", indicatorName);

        /** 解决 java 的json转到 python 会出现的双引号转义问题 */
//        String params = paramsObject.toString().replace("\"", "\\\"");
        return paramsObject;
    }


    /** 检测返回结果是否合法 */
    public boolean isFloat(String score) {
        try {
            // 尝试将字符串转换为 Float
            Float.parseFloat(score);
            return true;  // 如果转换成功，返回 true
        } catch (NumberFormatException e) {
            return false; // 如果抛出异常，表示不能转换为 Float
        }
    }

    /** 根据url 返回文件保存路径 ，这里默认的 type 为 supplement*/
    static String  getTrueFilePath(String url) {
        String dataType = "supplement";
        String basePath = RuoYiConfig.getUploadPath() + '/' + dataType;
        String dateFilePath = url.substring(url.indexOf('/'+dataType) + dataType.length() + 1);
        String trueFilePath = basePath + dateFilePath;

        return trueFilePath;
    }

    /**
     *  计算原始数据得分 -- 中国主导 CN_Lead / 中国参与 CN_Join by standardCode
     */
    public  Map<Integer,Float>  calScore(String standardCode,Integer type){
        List<StandardSystemData> systemDataList = standardSystemDataService.selectSystemDataByCode(standardCode);
        ISDataScoreUtil isDataScoreUtil = new ISDataScoreUtil();
        Map<Integer,String> indicatorMap = isDataScoreUtil.getIndicatorMap();

        // 记录 indicatorId : {usage1:data1,usage2:data2 }
        Map<Integer, Map<String, String>> id_UsageDataMap = new HashMap<>();

        for (StandardSystemData data : systemDataList) {
            Integer indicatorId = data.getIndicatorId().intValue();
            id_UsageDataMap.putIfAbsent(indicatorId, new HashMap<>());
            Map<String, String> usageDataMap = id_UsageDataMap.get(indicatorId);

            // 将 usage 和 data 存入
            usageDataMap.put(data.getUsage(), data.getData());
        }

        // 保存计算结果—— key:indicatorId value:score
        Map<Integer,Float> calRes = new HashMap<>();

        // 遍历, 获取每个 indicatorId和对应的 usage:data Map
        for (Map.Entry<Integer, Map<String, String>> entry : id_UsageDataMap.entrySet()) {
            // 外层ey: indicatorId
            Integer indicatorId = entry.getKey();
            String indicatorName = indicatorMap.get(indicatorId);
            // 外层value: usage:data 的内部 Map
            Map<String, String> usageDataMap = entry.getValue();
            // 获取params
            JSONObject params = getParams(usageDataMap,isDataScoreUtil.getParamsTypeMap(),indicatorName);

            System.out.println("params: "+params);
            if(params!=null){
                // 计算得分
                String score = null;
                if (type == 0){
                    score = isDataScoreUtil.calScore(0,params);
                }else if (type == 1){
                    score = isDataScoreUtil.calScore(1,params);
                }
                System.out.println("score: "+score);

                // 检测结果是否合法(Float)
                if (score!=null && isFloat(score)) {
                    Float value = Float.parseFloat(score);
                    calRes.put(indicatorId, value);
                }
            }
        }
        return calRes;
    }
}
